home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / usr / lib / python2.4 / gettext.pyo (.txt) < prev    next >
Python Compiled Bytecode  |  2005-10-18  |  15KB  |  598 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.4)
  3.  
  4. '''Internationalization and localization support.
  5.  
  6. This module provides internationalization (I18N) and localization (L10N)
  7. support for your Python programs by providing an interface to the GNU gettext
  8. message catalog library.
  9.  
  10. I18N refers to the operation by which a program is made aware of multiple
  11. languages.  L10N refers to the adaptation of your program, once
  12. internationalized, to the local language and cultural habits.
  13.  
  14. '''
  15. import locale
  16. import copy
  17. import os
  18. import re
  19. import struct
  20. import sys
  21. from errno import ENOENT
  22. __all__ = [
  23.     'NullTranslations',
  24.     'GNUTranslations',
  25.     'Catalog',
  26.     'find',
  27.     'translation',
  28.     'install',
  29.     'textdomain',
  30.     'bindtextdomain',
  31.     'dgettext',
  32.     'dngettext',
  33.     'gettext',
  34.     'ngettext']
  35. _default_localedir = os.path.join(sys.prefix, 'share', 'locale')
  36.  
  37. def test(condition, true, false):
  38.     '''
  39.     Implements the C expression:
  40.  
  41.       condition ? true : false
  42.  
  43.     Required to correctly interpret plural forms.
  44.     '''
  45.     if condition:
  46.         return true
  47.     else:
  48.         return false
  49.  
  50.  
  51. def c2py(plural):
  52.     '''Gets a C expression as used in PO files for plural forms and returns a
  53.     Python lambda function that implements an equivalent expression.
  54.     '''
  55.     StringIO = StringIO
  56.     import StringIO
  57.     import token as token
  58.     import tokenize as tokenize
  59.     tokens = tokenize.generate_tokens(StringIO(plural).readline)
  60.     
  61.     try:
  62.         danger = _[1]
  63.     except tokenize.TokenError:
  64.         raise ValueError, 'plural forms expression error, maybe unbalanced parenthesis'
  65.  
  66.     if danger:
  67.         raise ValueError, 'plural forms expression could be dangerous'
  68.     
  69.     plural = plural.replace('&&', ' and ')
  70.     plural = plural.replace('||', ' or ')
  71.     expr = re.compile('\\!([^=])')
  72.     plural = expr.sub(' not \\1', plural)
  73.     expr = re.compile('(.*?)\\?(.*?):(.*)')
  74.     
  75.     def repl(x):
  76.         return 'test(%s, %s, %s)' % (x.group(1), x.group(2), expr.sub(repl, x.group(3)))
  77.  
  78.     stack = [
  79.         '']
  80.     for c in plural:
  81.         if c == '(':
  82.             stack.append('')
  83.             continue
  84.         if c == ')':
  85.             if len(stack) == 1:
  86.                 raise ValueError, 'unbalanced parenthesis in plural form'
  87.             
  88.             s = expr.sub(repl, stack.pop())
  89.             stack[-1] += '(%s)' % s
  90.             continue
  91.         stack[-1] += c
  92.     
  93.     plural = expr.sub(repl, stack.pop())
  94.     return eval('lambda n: int(%s)' % plural)
  95.  
  96.  
  97. def _expand_lang(locale):
  98.     normalize = normalize
  99.     import locale
  100.     locale = normalize(locale)
  101.     COMPONENT_CODESET = 1 << 0
  102.     COMPONENT_TERRITORY = 1 << 1
  103.     COMPONENT_MODIFIER = 1 << 2
  104.     mask = 0
  105.     pos = locale.find('@')
  106.     if pos >= 0:
  107.         modifier = locale[pos:]
  108.         locale = locale[:pos]
  109.         mask |= COMPONENT_MODIFIER
  110.     else:
  111.         modifier = ''
  112.     pos = locale.find('.')
  113.     if pos >= 0:
  114.         codeset = locale[pos:]
  115.         locale = locale[:pos]
  116.         mask |= COMPONENT_CODESET
  117.     else:
  118.         codeset = ''
  119.     pos = locale.find('_')
  120.     if pos >= 0:
  121.         territory = locale[pos:]
  122.         locale = locale[:pos]
  123.         mask |= COMPONENT_TERRITORY
  124.     else:
  125.         territory = ''
  126.     language = locale
  127.     ret = []
  128.     for i in range(mask + 1):
  129.         if not i & ~mask:
  130.             val = language
  131.             if i & COMPONENT_TERRITORY:
  132.                 val += territory
  133.             
  134.             if i & COMPONENT_CODESET:
  135.                 val += codeset
  136.             
  137.             if i & COMPONENT_MODIFIER:
  138.                 val += modifier
  139.             
  140.             ret.append(val)
  141.             continue
  142.     
  143.     ret.reverse()
  144.     return ret
  145.  
  146.  
  147. class NullTranslations:
  148.     
  149.     def __init__(self, fp = None):
  150.         self._info = { }
  151.         self._charset = None
  152.         self._output_charset = None
  153.         self._fallback = None
  154.         if fp is not None:
  155.             self._parse(fp)
  156.         
  157.  
  158.     
  159.     def _parse(self, fp):
  160.         pass
  161.  
  162.     
  163.     def add_fallback(self, fallback):
  164.         if self._fallback:
  165.             self._fallback.add_fallback(fallback)
  166.         else:
  167.             self._fallback = fallback
  168.  
  169.     
  170.     def gettext(self, message):
  171.         if self._fallback:
  172.             return self._fallback.gettext(message)
  173.         
  174.         return message
  175.  
  176.     
  177.     def lgettext(self, message):
  178.         if self._fallback:
  179.             return self._fallback.lgettext(message)
  180.         
  181.         return message
  182.  
  183.     
  184.     def ngettext(self, msgid1, msgid2, n):
  185.         if self._fallback:
  186.             return self._fallback.ngettext(msgid1, msgid2, n)
  187.         
  188.         if n == 1:
  189.             return msgid1
  190.         else:
  191.             return msgid2
  192.  
  193.     
  194.     def lngettext(self, msgid1, msgid2, n):
  195.         if self._fallback:
  196.             return self._fallback.lngettext(msgid1, msgid2, n)
  197.         
  198.         if n == 1:
  199.             return msgid1
  200.         else:
  201.             return msgid2
  202.  
  203.     
  204.     def ugettext(self, message):
  205.         if self._fallback:
  206.             return self._fallback.ugettext(message)
  207.         
  208.         return unicode(message)
  209.  
  210.     
  211.     def ungettext(self, msgid1, msgid2, n):
  212.         if self._fallback:
  213.             return self._fallback.ungettext(msgid1, msgid2, n)
  214.         
  215.         if n == 1:
  216.             return unicode(msgid1)
  217.         else:
  218.             return unicode(msgid2)
  219.  
  220.     
  221.     def info(self):
  222.         return self._info
  223.  
  224.     
  225.     def charset(self):
  226.         return self._charset
  227.  
  228.     
  229.     def output_charset(self):
  230.         return self._output_charset
  231.  
  232.     
  233.     def set_output_charset(self, charset):
  234.         self._output_charset = charset
  235.  
  236.     
  237.     def install(self, unicode = False):
  238.         import __builtin__ as __builtin__
  239.         if not unicode or self.ugettext:
  240.             pass
  241.         __builtin__.__dict__['_'] = self.gettext
  242.  
  243.  
  244.  
  245. class GNUTranslations(NullTranslations):
  246.     LE_MAGIC = 0x950412DEL
  247.     BE_MAGIC = 0xDE120495L
  248.     
  249.     def _parse(self, fp):
  250.         '''Override this method to support alternative .mo formats.'''
  251.         unpack = struct.unpack
  252.         filename = getattr(fp, 'name', '')
  253.         self._catalog = catalog = { }
  254.         
  255.         self.plural = lambda n: int(n != 1)
  256.         buf = fp.read()
  257.         buflen = len(buf)
  258.         magic = unpack('<I', buf[:4])[0]
  259.         if magic == self.LE_MAGIC:
  260.             (version, msgcount, masteridx, transidx) = unpack('<4I', buf[4:20])
  261.             ii = '<II'
  262.         elif magic == self.BE_MAGIC:
  263.             (version, msgcount, masteridx, transidx) = unpack('>4I', buf[4:20])
  264.             ii = '>II'
  265.         else:
  266.             raise IOError(0, 'Bad magic number', filename)
  267.         for i in xrange(0, msgcount):
  268.             (mlen, moff) = unpack(ii, buf[masteridx:masteridx + 8])
  269.             mend = moff + mlen
  270.             (tlen, toff) = unpack(ii, buf[transidx:transidx + 8])
  271.             tend = toff + tlen
  272.             if mend < buflen and tend < buflen:
  273.                 msg = buf[moff:mend]
  274.                 tmsg = buf[toff:tend]
  275.             else:
  276.                 raise IOError(0, 'File is corrupt', filename)
  277.             if mlen == 0:
  278.                 lastk = None
  279.                 k = None
  280.                 for item in tmsg.splitlines():
  281.                     item = item.strip()
  282.                     if not item:
  283.                         continue
  284.                     
  285.                     if ':' in item:
  286.                         (k, v) = item.split(':', 1)
  287.                         k = k.strip().lower()
  288.                         v = v.strip()
  289.                         self._info[k] = v
  290.                         lastk = k
  291.                     elif lastk:
  292.                         self._info[lastk] += '\n' + item
  293.                     
  294.                     if k == 'content-type':
  295.                         self._charset = v.split('charset=')[1]
  296.                         continue
  297.                     if k == 'plural-forms':
  298.                         v = v.split(';')
  299.                         plural = v[1].split('plural=')[1]
  300.                         self.plural = c2py(plural)
  301.                         continue
  302.                 
  303.             
  304.             if '\x00' in msg:
  305.                 (msgid1, msgid2) = msg.split('\x00')
  306.                 tmsg = tmsg.split('\x00')
  307.                 for i in range(len(tmsg)):
  308.                     catalog[(msgid1, i)] = tmsg[i]
  309.                 
  310.             elif self._charset:
  311.                 msg = unicode(msg, self._charset)
  312.                 tmsg = unicode(tmsg, self._charset)
  313.             
  314.             catalog[msg] = tmsg
  315.             masteridx += 8
  316.             transidx += 8
  317.         
  318.  
  319.     
  320.     def gettext(self, message):
  321.         missing = object()
  322.         tmsg = self._catalog.get(message, missing)
  323.         if tmsg is missing:
  324.             if self._fallback:
  325.                 return self._fallback.gettext(message)
  326.             
  327.             return message
  328.         
  329.         if self._output_charset:
  330.             return tmsg.encode(self._output_charset)
  331.         elif self._charset:
  332.             return tmsg.encode(self._charset)
  333.         
  334.         return tmsg
  335.  
  336.     
  337.     def lgettext(self, message):
  338.         missing = object()
  339.         tmsg = self._catalog.get(message, missing)
  340.         if tmsg is missing:
  341.             if self._fallback:
  342.                 return self._fallback.lgettext(message)
  343.             
  344.             return message
  345.         
  346.         if self._output_charset:
  347.             return tmsg.encode(self._output_charset)
  348.         
  349.         return tmsg.encode(locale.getpreferredencoding())
  350.  
  351.     
  352.     def ngettext(self, msgid1, msgid2, n):
  353.         
  354.         try:
  355.             tmsg = self._catalog[(msgid1, self.plural(n))]
  356.             if self._output_charset:
  357.                 return tmsg.encode(self._output_charset)
  358.             elif self._charset:
  359.                 return tmsg.encode(self._charset)
  360.             
  361.             return tmsg
  362.         except KeyError:
  363.             if self._fallback:
  364.                 return self._fallback.ngettext(msgid1, msgid2, n)
  365.             
  366.             if n == 1:
  367.                 return msgid1
  368.             else:
  369.                 return msgid2
  370.         except:
  371.             n == 1
  372.  
  373.  
  374.     
  375.     def lngettext(self, msgid1, msgid2, n):
  376.         
  377.         try:
  378.             tmsg = self._catalog[(msgid1, self.plural(n))]
  379.             if self._output_charset:
  380.                 return tmsg.encode(self._output_charset)
  381.             
  382.             return tmsg.encode(locale.getpreferredencoding())
  383.         except KeyError:
  384.             if self._fallback:
  385.                 return self._fallback.lngettext(msgid1, msgid2, n)
  386.             
  387.             if n == 1:
  388.                 return msgid1
  389.             else:
  390.                 return msgid2
  391.         except:
  392.             n == 1
  393.  
  394.  
  395.     
  396.     def ugettext(self, message):
  397.         missing = object()
  398.         tmsg = self._catalog.get(message, missing)
  399.         if tmsg is missing:
  400.             if self._fallback:
  401.                 return self._fallback.ugettext(message)
  402.             
  403.             return unicode(message)
  404.         
  405.         return tmsg
  406.  
  407.     
  408.     def ungettext(self, msgid1, msgid2, n):
  409.         
  410.         try:
  411.             tmsg = self._catalog[(msgid1, self.plural(n))]
  412.         except KeyError:
  413.             if self._fallback:
  414.                 return self._fallback.ungettext(msgid1, msgid2, n)
  415.             
  416.             if n == 1:
  417.                 tmsg = unicode(msgid1)
  418.             else:
  419.                 tmsg = unicode(msgid2)
  420.         except:
  421.             n == 1
  422.  
  423.         return tmsg
  424.  
  425.  
  426.  
  427. def find(domain, localedir = None, languages = None, all = 0):
  428.     if localedir is None:
  429.         localedir = _default_localedir
  430.     
  431.     if languages is None:
  432.         languages = []
  433.         for envar in ('LANGUAGE', 'LC_ALL', 'LC_MESSAGES', 'LANG'):
  434.             val = os.environ.get(envar)
  435.             if val:
  436.                 languages = val.split(':')
  437.                 break
  438.                 continue
  439.         
  440.         if 'C' not in languages:
  441.             languages.append('C')
  442.         
  443.     
  444.     nelangs = []
  445.     for lang in languages:
  446.         for nelang in _expand_lang(lang):
  447.             if nelang not in nelangs:
  448.                 nelangs.append(nelang)
  449.                 continue
  450.         
  451.     
  452.     if all:
  453.         result = []
  454.     else:
  455.         result = None
  456.     for lang in nelangs:
  457.         if lang == 'C':
  458.             break
  459.         
  460.         mofile = os.path.join(localedir, lang, 'LC_MESSAGES', '%s.mo' % domain)
  461.         if os.path.exists(mofile):
  462.             if all:
  463.                 result.append(mofile)
  464.             else:
  465.                 return mofile
  466.         all
  467.     
  468.     return result
  469.  
  470. _translations = { }
  471.  
  472. def translation(domain, localedir = None, languages = None, class_ = None, fallback = False, codeset = None):
  473.     if class_ is None:
  474.         class_ = GNUTranslations
  475.     
  476.     mofiles = find(domain, localedir, languages, all = 1)
  477.     if not mofiles:
  478.         if fallback:
  479.             return NullTranslations()
  480.         
  481.         raise IOError(ENOENT, 'No translation file found for domain', domain)
  482.     
  483.     result = None
  484.     for mofile in mofiles:
  485.         key = os.path.abspath(mofile)
  486.         t = _translations.get(key)
  487.         if t is None:
  488.             t = _translations.setdefault(key, class_(open(mofile, 'rb')))
  489.         
  490.         t = copy.copy(t)
  491.         if codeset:
  492.             t.set_output_charset(codeset)
  493.         
  494.         if result is None:
  495.             result = t
  496.             continue
  497.         result.add_fallback(t)
  498.     
  499.     return result
  500.  
  501.  
  502. def install(domain, localedir = None, unicode = False, codeset = None):
  503.     t = translation(domain, localedir, fallback = True, codeset = codeset)
  504.     t.install(unicode)
  505.  
  506. _localedirs = { }
  507. _localecodesets = { }
  508. _current_domain = 'messages'
  509.  
  510. def textdomain(domain = None):
  511.     global _current_domain
  512.     if domain is not None:
  513.         _current_domain = domain
  514.     
  515.     return _current_domain
  516.  
  517.  
  518. def bindtextdomain(domain, localedir = None):
  519.     if localedir is not None:
  520.         _localedirs[domain] = localedir
  521.     
  522.     return _localedirs.get(domain, _default_localedir)
  523.  
  524.  
  525. def bind_textdomain_codeset(domain, codeset = None):
  526.     if codeset is not None:
  527.         _localecodesets[domain] = codeset
  528.     
  529.     return _localecodesets.get(domain)
  530.  
  531.  
  532. def dgettext(domain, message):
  533.     
  534.     try:
  535.         t = translation(domain, _localedirs.get(domain, None), codeset = _localecodesets.get(domain))
  536.     except IOError:
  537.         return message
  538.  
  539.     return t.gettext(message)
  540.  
  541.  
  542. def ldgettext(domain, message):
  543.     
  544.     try:
  545.         t = translation(domain, _localedirs.get(domain, None), codeset = _localecodesets.get(domain))
  546.     except IOError:
  547.         return message
  548.  
  549.     return t.lgettext(message)
  550.  
  551.  
  552. def dngettext(domain, msgid1, msgid2, n):
  553.     
  554.     try:
  555.         t = translation(domain, _localedirs.get(domain, None), codeset = _localecodesets.get(domain))
  556.     except IOError:
  557.         if n == 1:
  558.             return msgid1
  559.         else:
  560.             return msgid2
  561.     except:
  562.         n == 1
  563.  
  564.     return t.ngettext(msgid1, msgid2, n)
  565.  
  566.  
  567. def ldngettext(domain, msgid1, msgid2, n):
  568.     
  569.     try:
  570.         t = translation(domain, _localedirs.get(domain, None), codeset = _localecodesets.get(domain))
  571.     except IOError:
  572.         if n == 1:
  573.             return msgid1
  574.         else:
  575.             return msgid2
  576.     except:
  577.         n == 1
  578.  
  579.     return t.lngettext(msgid1, msgid2, n)
  580.  
  581.  
  582. def gettext(message):
  583.     return dgettext(_current_domain, message)
  584.  
  585.  
  586. def lgettext(message):
  587.     return ldgettext(_current_domain, message)
  588.  
  589.  
  590. def ngettext(msgid1, msgid2, n):
  591.     return dngettext(_current_domain, msgid1, msgid2, n)
  592.  
  593.  
  594. def lngettext(msgid1, msgid2, n):
  595.     return ldngettext(_current_domain, msgid1, msgid2, n)
  596.  
  597. Catalog = translation
  598.